package com.tanhua.server.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.tanhua.autoconfig.template.HuanXinTemplate;
import com.tanhua.autoconfig.template.SmsTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.commons.utils.JwtUtils;
import com.tanhua.dubbo.api.UserApi;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.UserlikeApi;
import com.tanhua.dubbo.api.VisitorsApi;
import com.tanhua.model.domain.User;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.mongo.UserLike;
import com.tanhua.model.mongo.Visitors;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.FriendVo;
import com.tanhua.model.vo.PageResult;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import com.tanhua.server.service.UserFreezeService;
import com.tanhua.server.service.UserService;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private SmsTemplate smsTemplate;

    @DubboReference
    private UserApi userApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @DubboReference
    private UserlikeApi userlikeApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    @Autowired
    private UserFreezeService userFreezeService;

    @Autowired
    private AmqpTemplate amqpTemplate;

    @Autowired
    private MqMessageService mqMessageService;
    /**
     * 发送短信验证码
     *
     * @param phone
     */
    @Override
    public void sendMsg(String phone) {
        //根据手机号码查询用户，如果用户存在判断是否被冻结
        User user = userApi.findByMobile(phone);
        if (user!=null){
            userFreezeService.checkStatus(user.getId(),"1");
        }

        //随机生成6位数字
//        String code = RandomStringUtils.randomNumeric(6);
        String code = "123456";
        //调用template对象发送收集短信
//            smsTemplate.sendSms(phone, code);

        //验证码存入Redis
        redisTemplate.opsForValue().set("CHECK_CODE_" + phone, code, 5, TimeUnit.MINUTES);

    }

    /**
     * 核对验证码并颁发token（登录）
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public Map loginVerification(String phone, String code) {
        //1.从Redis中取出验证码
        String redisCode = redisTemplate.opsForValue().get("CHECK_CODE_" + phone);
        //2.校验验证码是否和输入的一致
        if (StringUtils.isEmpty(redisCode) || !code.equals(redisCode)) {
            throw new BusinessException(ErrorResult.loginError());
        }
        //3.删除Redis缓存的验证码
        redisTemplate.delete("CHECK_CODE_" + phone);

        //4.通过手机号查询用户
        User user = userApi.findByMobile(phone);
        boolean isNew = false;

        //4.1 如果用户不存在，将用户保存到数据库中
        String type = "0101";
        if (user == null) {
            type = "0102";
            user = new User();
            user.setMobile(phone);
            user.setPassword(DigestUtils.md5DigestAsHex("123456".getBytes()));
            Long userId = userApi.save(user);
            user.setId(userId);
            isNew = true;

            //注册环信用户
            String hxusername = "hx" + user.getId();
            Boolean flag = huanXinTemplate.createUser(hxusername, Constants.INIT_PASSWORD);
            if (flag) { //判断新用户是否创建成功
                user.setHxUser(hxusername);
                user.setHxPassword(Constants.INIT_PASSWORD);
                userApi.update(user);
            }
        }
        mqMessageService.sendLogMessage(user.getId(), type,"user",null);

        //5.通过JWT生成token（存入ID和手机号）
        Map tokenMap = new HashMap();
        tokenMap.put("id", user.getId());
        tokenMap.put("mobile", phone);
        String token = JwtUtils.getToken(tokenMap); //jwt工具类

        //6.通过构造返回值
        Map resultMap = new HashMap();
        resultMap.put("token", token);
        resultMap.put("isNew", isNew);

        return resultMap;
    }

    /**
     * 核对验证码（修改手机号）
     *
     * @param phone
     * @param code
     * @return
     */
    @Override
    public Map checkCode(String phone, String code) {
        //1.从Redis中取出验证码
        String redisCode = redisTemplate.opsForValue().get("CHECK_CODE_" + phone);
        //2.校验验证码是否和输入的一致
        if (StringUtils.isEmpty(redisCode) || !code.equals(redisCode)) {
            throw new BusinessException(ErrorResult.loginError());
        }
        //3.删除Redis缓存的验证码
        redisTemplate.delete("CHECK_CODE_" + phone);
        Map map = new HashMap();
        map.put("verification", true);
        return map;
    }

    @Override
    public void updatePhone(String phone) {
        User user = new User();
        user.setId(UserHolder.getUserId());
        user.setMobile(phone);
        userApi.updatePhone(user);
    }

    @Override
    public Map counts() {
        Map map = userlikeApi.counts(UserHolder.getUserId());
        return map;
    }

    /**
     * 查看“互相喜欢，喜欢，粉丝，谁看过我”列表
     * @param type
     * @param page
     * @param pagesize
     * @return
     */
    @Override
    public PageResult list(String type, int page, int pagesize) {
        if ("1".equals(type)) {
            List<UserLike> list = userlikeApi.findEachLike(UserHolder.getUserId());
            if (CollUtil.isEmpty(list)){
                return  new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(list, "userId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (UserLike like : list) {
                UserInfo userInfo = map.get(like.getUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    vo.setAlreadyLove(true);
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("2".equals(type)){
            List<UserLike> userLikes = userlikeApi.getUserLikes(UserHolder.getUserId());
            if (CollUtil.isEmpty(userLikes)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(userLikes, "likeUserId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (UserLike like : userLikes) {
                UserInfo userInfo = map.get(like.getLikeUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    vo.setAlreadyLove(true);
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("3".equals(type)){
            List<UserLike> likeMeUsers = userlikeApi.getLikeMeUser(UserHolder.getUserId());
            if (CollUtil.isEmpty(likeMeUsers)){
                return new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(likeMeUsers, "userId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (UserLike like : likeMeUsers) {
                UserInfo userInfo = map.get(like.getUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    //查询我是否也喜欢了当前用户
                    Boolean flag = userlikeApi.likeOrNot(UserHolder.getUserId(),like.getUserId());
                    if (flag){
                        vo.setAlreadyLove(true);
                    }else {
                        vo.setAlreadyLove(false);
                    }
                    voList.add(vo);
                }
            }
            return new PageResult(page,pagesize,0L,voList);
        }else if ("4".equals(type)){
            List<Visitors> list = visitorsApi.queryAllVisitorsList(UserHolder.getUserId());
            if (CollUtil.isEmpty(list)){
                return  new PageResult();
            }
            List<Long> userIds = CollUtil.getFieldValues(list, "visitorUserId", Long.class);
            Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, null);
            List<FriendVo> voList = new ArrayList<>();
            for (Visitors visitors : list) {
                UserInfo userInfo = map.get(visitors.getVisitorUserId());
                if (userInfo!=null){
                    FriendVo vo = new FriendVo();
                    BeanUtils.copyProperties(userInfo,vo);
                    vo.setMatchRate(RandomUtil.randomInt(30,99));
                    //查询当前操作用户是否也喜欢了指定用户
                    Boolean flag = userlikeApi.likeOrNot(UserHolder.getUserId(),visitors.getVisitorUserId());
                    if (flag){
                        vo.setAlreadyLove(true);
                    }else {
                        vo.setAlreadyLove(false);
                    }
                    voList.add(vo);
                }
            }
            String key = Constants.VISITORS_USER;
            String hashKey = UserHolder.getUserId().toString();
            String value = String.valueOf(System.currentTimeMillis());
            redisTemplate.opsForHash().put(key,hashKey,value);
            return new PageResult(page,pagesize,0L,voList);
        }else {
            throw new BusinessException(ErrorResult.error());
        }
    }
}
